using System;
using System.Collections.Generic;
using Volo.Abp;
using Volo.Abp.Domain.Entities.Auditing;
using Volo.Abp.Domain.Services;
using Matrix.ServiceDiscovery.Enums;

namespace Matrix.ServiceDiscovery.Entities;

/// <summary>
/// 服务实例实体
/// </summary>
public class ServiceInstance : FullAuditedEntity<Guid>
{
    /// <summary>
    /// 服务ID
    /// </summary>
    public virtual Guid ServiceId { get; protected set; }

    /// <summary>
    /// 服务名称
    /// </summary>
    public virtual string ServiceName { get; protected set; } = string.Empty;

    /// <summary>
    /// 实例ID（业务标识）
    /// </summary>
    public virtual string InstanceId { get; protected set; } = string.Empty;

    /// <summary>
    /// 主机地址
    /// </summary>
    public virtual string Host { get; protected set; } = string.Empty;

    /// <summary>
    /// 端口号
    /// </summary>
    public virtual int Port { get; protected set; }

    /// <summary>
    /// 协议类型
    /// </summary>
    public virtual string Protocol { get; protected set; } = "HTTP";

    /// <summary>
    /// 权重
    /// </summary>
    public virtual int Weight { get; protected set; } = 1;

    /// <summary>
    /// 健康状态
    /// </summary>
    public virtual HealthStatus HealthStatus { get; protected set; }

    /// <summary>
    /// 区域
    /// </summary>
    public virtual string? Region { get; protected set; }

    /// <summary>
    /// 可用区
    /// </summary>
    public virtual string? Zone { get; protected set; }

    /// <summary>
    /// 标签
    /// </summary>
    public virtual List<string> Tags { get; protected set; } = new();

    /// <summary>
    /// 元数据
    /// </summary>
    public virtual Dictionary<string, object> Metadata { get; protected set; } = new();

    /// <summary>
    /// 最后心跳时间
    /// </summary>
    public virtual DateTime? LastHeartbeatTime { get; protected set; }

    /// <summary>
    /// 服务信息
    /// </summary>
    public virtual ServiceInfo Service { get; protected set; } = null!;

    protected ServiceInstance() { }

    public ServiceInstance(
        Guid id,
        Guid serviceId,
        string serviceName,
        string instanceId,
        string host,
        int port,
        string protocol = "HTTP",
        int weight = 1,
        string? region = null,
        string? zone = null) : base(id)
    {
        ServiceId = serviceId;
        ServiceName = serviceName;
        InstanceId = instanceId;
        Host = host;
        Port = port;
        Protocol = protocol;
        Weight = weight;
        Region = region;
        Zone = zone;
        HealthStatus = HealthStatus.Healthy;
        LastHeartbeatTime = DateTime.UtcNow;
    }

    public void UpdateHealthStatus(HealthStatus status)
    {
        HealthStatus = status;
    }

    public void RecordHeartbeat()
    {
        LastHeartbeatTime = DateTime.UtcNow;
        if (HealthStatus == HealthStatus.Unhealthy)
        {
            HealthStatus = HealthStatus.Healthy;
        }
    }

    public void AddTag(string tag)
    {
        if (!Tags.Contains(tag))
        {
            Tags.Add(tag);
        }
    }

    public void RemoveTag(string tag)
    {
        Tags.Remove(tag);
    }

    public void SetMetadata(string key, object value)
    {
        Metadata[key] = value;
    }

    public void RemoveMetadata(string key)
    {
        Metadata.Remove(key);
    }
}